package com.ljd.sps;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class AdjustActivity extends Activity implements OnClickListener, OnSeekBarChangeListener {
	private static final String TAG = "ljd";
	
	public static boolean FRONT_CAMERA;
    
    private ImageView mPhoto;
    
    private Bitmap srcBitmap, destBitmap;
    private int imgHeight, imgWidth;  
    private int mBrightness, mRed, mGreen, mBlue;
    private float mContrast = 1;
    private int mType;
    private Dialog dialog;
    
    private ProgressDialog mProgressDialog;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.adjust);
        
        mPhoto = (ImageView)findViewById(R.id.photo);
//    	mPhoto.setImageResource(R.drawable.xxx);
    	
        findViewById(R.id.reset).setOnClickListener(this);
        findViewById(R.id.done).setOnClickListener(this);
        findViewById(R.id.ev).setOnClickListener(this);
        findViewById(R.id.color).setOnClickListener(this);
        findViewById(R.id.clear).setOnClickListener(this);
        findViewById(R.id.undo).setOnClickListener(this);
        findViewById(R.id.finish).setOnClickListener(this);
        
        ((SeekBar)findViewById(R.id.brightness)).setOnSeekBarChangeListener(this);
        ((SeekBar)findViewById(R.id.contrast)).setOnSeekBarChangeListener(this);
        ((SeekBar)findViewById(R.id.red)).setOnSeekBarChangeListener(this);
        ((SeekBar)findViewById(R.id.green)).setOnSeekBarChangeListener(this);
        ((SeekBar)findViewById(R.id.blue)).setOnSeekBarChangeListener(this);
    }
    
    @Override  
    public boolean onKeyDown(int keyCode, KeyEvent event) {  
        if (keyCode == KeyEvent.KEYCODE_BACK) {
        	if (findViewById(R.id.button_panel).getVisibility() == View.VISIBLE) {
    			Intent intent = new Intent(this, TakePhotoActivity.class);
    			intent.putExtra(SmallphoneScannerActivity.EXTRA_PHOTO_TYPE, mType);
    			startActivity(intent);
    			finish();
        		return true;  
        	}
        }  
        return super.onKeyDown(keyCode, event);  
    }

	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.reset:
			Intent intent = new Intent(this, TakePhotoActivity.class);
			intent.putExtra(SmallphoneScannerActivity.EXTRA_PHOTO_TYPE, mType);
			startActivity(intent);
			finish();
			break;
		case R.id.done:
			findViewById(R.id.button_panel).setVisibility(View.GONE);
			findViewById(R.id.button_panel_2).setVisibility(View.VISIBLE);
			findViewById(R.id.color_control).setVisibility(View.VISIBLE);
			findViewById(R.id.icn_color).setVisibility(View.VISIBLE);
			undoSeekBar();
			showDialog(0);
			break;
		case R.id.ev:
			findViewById(R.id.ev_control).setVisibility(View.VISIBLE);
			findViewById(R.id.icn_ev).setVisibility(View.VISIBLE);
			findViewById(R.id.color_control).setVisibility(View.GONE);
			findViewById(R.id.icn_color).setVisibility(View.GONE);
			break;
		case R.id.color:
			findViewById(R.id.ev_control).setVisibility(View.GONE);
			findViewById(R.id.icn_ev).setVisibility(View.GONE);
			findViewById(R.id.color_control).setVisibility(View.VISIBLE);
			findViewById(R.id.icn_color).setVisibility(View.VISIBLE);
			break;
		case R.id.clear:
			clearSeekBar();
			break;
		case R.id.undo:
			undoSeekBar();
			break;
		case R.id.finish:
			savePhoto();
			break;
		case R.id.yes:
			dialog.cancel();
			break;
		case R.id.no:
			dialog.cancel();
			savePhoto();
			break;
		}
	}
	
	public void onResume() {
		super.onResume();
		initImage();
	}
	
	public void onDestroy() {
		super.onDestroy();
		
		if (mProgressDialog != null) {
			mProgressDialog.dismiss();
			mProgressDialog = null;
		}
		
		srcBitmap.recycle();
		srcBitmap = null;
		
		destBitmap.recycle();
		destBitmap = null;

    	((BitmapDrawable)mPhoto.getDrawable()).getBitmap().recycle();
    	mPhoto.setImageBitmap(null);
    	
    	if (SmallphoneScannerActivity.LOG) {
    		Log.i(TAG, "adjust activity onDestroy");
    	}
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		LayoutInflater inflater = LayoutInflater.from(this);
		View view = inflater.inflate(R.layout.dialogadjustphoto, null);
		view.findViewById(R.id.yes).setOnClickListener(this);
		view.findViewById(R.id.no).setOnClickListener(this);
		dialog = new Dialog(this, R.style.dialog);
		dialog.setContentView(view);
		return dialog;
	}

	private void savePhoto() {
		new SavePictureTask().execute(null);
    	
    	mProgressDialog = new ProgressDialog(this);
    	mProgressDialog.setCancelable(false);
    	mProgressDialog.show();
	}
	
	// save pic   
    class SavePictureTask extends AsyncTask<byte[], String, String> {
    	
        @Override  
        protected String doInBackground(byte[]... params) {
    		ColorMatrix cMatrix;
    		Paint paint;
    		Canvas canvas;
    		BitmapRegionDecoder regionDecoder;
    		Bitmap src = null;
			try {
				regionDecoder = BitmapRegionDecoder.newInstance(getFilesDir() + "/src.jpg", true);
//				Options option = new Options();
//
//				if (mType == SmallphoneScannerActivity._3X5 || mType == SmallphoneScannerActivity._4X6) {
//					option.inPreferredConfig = Config.RGB_565;
//				}
//				option.inPurgeable = true;
//				option.inInputShareable = true;
//	    		src = BitmapFactory.decodeFile(getFilesDir() + "/src.jpg", option);
	    		
	    		int degree = Util.getImageRotateDegree(getFilesDir() + "/src.jpg");
	        	if(degree != 0){
	                if (FRONT_CAMERA) {
	                	degree = -degree;
	                }
					if (mType == SmallphoneScannerActivity._3X5 || mType == SmallphoneScannerActivity._4X6) {
		                src = Bitmap.createBitmap(regionDecoder.getHeight(), regionDecoder.getWidth(), Config.RGB_565);
					} else {
						src = Bitmap.createBitmap(regionDecoder.getHeight(), regionDecoder.getWidth(), Config.ARGB_8888);
					}
	                rotateLargeBitmap(degree, regionDecoder, src);
	                
//	                Matrix mat = new Matrix();
//	                if (FRONT_CAMERA) {
//	                	mat.postRotate(-degree);
//	                }else {
//	                	mat.postRotate(degree);
//	                }
//
//	                System.gc();
//	                
//					try {
//						Thread.sleep(1000);
//					} catch (InterruptedException e1) {
//						// TODO Auto-generated catch block
//						e1.printStackTrace();
//					}
//					
//					src = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), mat, true);
	            } else {
	            	src = Bitmap.createBitmap(regionDecoder.getWidth(), regionDecoder.getHeight(), Config.ARGB_8888);
	            }
	        	
	            canvas = new Canvas(src);
	        	switch(mType) {
	        	case SmallphoneScannerActivity._NEGATIVES:
	        		cMatrix = new ColorMatrix();
		            cMatrix.set(new float[] { -1, 0, 0, 0, 255, 
		            		0, -1, 0, 0, 255,  
		                    0, 0, -1, 0, 255, 
		                    0, 0, 0, 1, 0 });
		
		            paint = new Paint();  
		            paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));  
		
		            canvas.drawBitmap(src, 0, 0, paint);
	    			break;
	        	}

	    		cMatrix = new ColorMatrix();
	            cMatrix.set(new float[] { mContrast, 0, 0, 0, mBrightness+mRed, 
	            		0, mContrast, 0, 0, mBrightness+mGreen,  
	                    0, 0, mContrast, 0, mBrightness+mBlue, 
	                    0, 0, 0, 1, 0 });

	            paint = new Paint();  
	            paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));

	            canvas.drawBitmap(src, 0, 0, paint);
	            
	            File file = new File(getFilesDir() + "/dest.jpg");
	            FileOutputStream out = new FileOutputStream(file);
                if (src.compress(Bitmap.CompressFormat.JPEG, 100, out)) {
                    out.flush();
                    out.close();
                }

                src.recycle();
                src = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
            
            return null;
        }

		@Override
		protected void onPostExecute(String result) {
			if (mProgressDialog != null) {
				mProgressDialog.dismiss();
				mProgressDialog = null;
			}

			SmallphoneScannerActivity.isFinished = true;
			finish();
		}
    }
	
	private void initImage() {
    	mType = getIntent().getIntExtra(SmallphoneScannerActivity.EXTRA_PHOTO_TYPE, 0);
    	srcBitmap = Util.loadBitmapWithSizeLimitation(this, 1024*1024, "src.jpg", getFilesDir().getAbsolutePath());
    	if (srcBitmap != null) {
    		int degree = Util.getImageRotateDegree(getFilesDir() + "/src.jpg");
    		if (SmallphoneScannerActivity.LOG) {
    			Log.i(TAG, "degres is " + degree);
    		}
        	if(degree != 0){
                Matrix mat = new Matrix();
                if (FRONT_CAMERA) {
                	mat.postRotate(-degree);
                }else {
                	mat.postRotate(degree);
                }
                srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), mat, true);     
            }
        	
        	imgHeight = srcBitmap.getHeight();  
            imgWidth = srcBitmap.getWidth();  
        	mPhoto.setImageBitmap(srcBitmap);
        	
        	destBitmap = Bitmap.createBitmap(imgWidth, imgHeight, Config.ARGB_8888);
        	switch(mType) {
        	case SmallphoneScannerActivity._NEGATIVES:
    			autoConfig();
    			break;
        	}
    	}
	}
	
	private void autoConfig() {
		ColorMatrix cMatrix;
		Paint paint;
		Canvas canvas;
		
        cMatrix = new ColorMatrix();
        cMatrix.set(new float[] { -1, 0, 0, 0, 255, 
        		0, -1, 0, 0, 255,  
                0, 0, -1, 0, 255, 
                0, 0, 0, 1, 0 });

        paint = new Paint();  
        paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));  

        canvas = new Canvas(srcBitmap);
        // 在Canvas上绘制一个已经存在的Bitmap。这样，dstBitmap就和srcBitmap一摸一样了   
        canvas.drawBitmap(srcBitmap, 0, 0, paint);
        mPhoto.setImageBitmap(srcBitmap);
	}
	
	private void configSeekBar(int brightness, int contrast, int red, int green, int blue) {

		SeekBar seek = (SeekBar)findViewById(R.id.brightness);
		seek.setProgress(brightness);

		seek = (SeekBar)findViewById(R.id.contrast);
		seek.setProgress(contrast);

		seek = (SeekBar)findViewById(R.id.red);
		seek.setProgress(red);

		seek = (SeekBar)findViewById(R.id.green);
		seek.setProgress(green);

		seek = (SeekBar)findViewById(R.id.blue);
		seek.setProgress(blue);
	}
	
	private void undoSeekBar() {
    	switch(mType) {
    	case SmallphoneScannerActivity._NEGATIVES:
//    		configSeekBar(195, 0, 77, 130, 148);
    		configSeekBar(127, 63, 127, 127, 127);
			break;
    	case SmallphoneScannerActivity._SLIDER:
//    		configSeekBar(122, 70, 113, 121, 136);
    		configSeekBar(127, 63, 127, 127, 127);
    		break;
    	case SmallphoneScannerActivity._3X5:
    	case SmallphoneScannerActivity._4X6:
    		configSeekBar(127, 63, 127, 127, 127);
    		break;
    	}
	}
	
	private void clearSeekBar() {
		configSeekBar(127, 63, 127, 127, 127);
	}

	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
		if (SmallphoneScannerActivity.LOG) {
			Log.i(TAG, "onProgressChanged:"+progress);
		}
		ColorMatrix cMatrix;
		Paint paint;
		Canvas canvas;
		switch (seekBar.getId()) {
		case R.id.brightness:
            mBrightness = 127 - progress;  
            
            cMatrix = new ColorMatrix();
            cMatrix.set(new float[] { mContrast, 0, 0, 0, mBrightness+mRed, 
            		0, mContrast, 0, 0, mBrightness+mGreen,  
                    0, 0, mContrast, 0, mBrightness+mBlue, 
                    0, 0, 0, 1, 0 });  

            paint = new Paint();  
            paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));  

            canvas = new Canvas(destBitmap);  
            // 在Canvas上绘制一个已经存在的Bitmap。这样，dstBitmap就和srcBitmap一摸一样了   
            canvas.drawBitmap(srcBitmap, 0, 0, paint);  
            mPhoto.setImageBitmap(destBitmap);  
			break;
		case R.id.contrast:
            // int brightness = progress - 127;
            mContrast = (float) ((127 - progress + 64) / 128.0);
            cMatrix = new ColorMatrix();
            cMatrix.set(new float[] { mContrast, 0, 0, 0, mBrightness+mRed, 
            		0, mContrast, 0, 0, mBrightness+mGreen,
                    0, 0, mContrast, 0, mBrightness+mBlue, 
                    0, 0, 0, 1, 0 });  

            paint = new Paint();  
            paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));  

            canvas = new Canvas(destBitmap);  
            // 在Canvas上绘制一个已经存在的Bitmap。这样，dstBitmap就和srcBitmap一摸一样了   
            canvas.drawBitmap(srcBitmap, 0, 0, paint);  
            mPhoto.setImageBitmap(destBitmap);  
			break;
		case R.id.red:
            mRed = 127 - progress;  
            cMatrix = new ColorMatrix();  
            cMatrix.set(new float[] { mContrast, 0, 0, 0, mBrightness+mRed, 
            		0, mContrast, 0, 0, mBrightness+mGreen,
                    0, 0, mContrast, 0, mBrightness+mBlue, 
                    0, 0, 0, 1, 0 });  

            paint = new Paint();  
            paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));  

            canvas = new Canvas(destBitmap);  
            // 在Canvas上绘制一个已经存在的Bitmap。这样，dstBitmap就和srcBitmap一摸一样了   
            canvas.drawBitmap(srcBitmap, 0, 0, paint);  
            mPhoto.setImageBitmap(destBitmap); 
			break;
		case R.id.green: 
            mGreen = 127 - progress;  
            cMatrix = new ColorMatrix();  
            cMatrix.set(new float[] { mContrast, 0, 0, 0, mBrightness+mRed, 
            		0, mContrast, 0, 0, mBrightness+mGreen,
                    0, 0, mContrast, 0, mBrightness+mBlue, 
                    0, 0, 0, 1, 0 });  

            paint = new Paint();  
            paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));  

            canvas = new Canvas(destBitmap);  
            // 在Canvas上绘制一个已经存在的Bitmap。这样，dstBitmap就和srcBitmap一摸一样了   
            canvas.drawBitmap(srcBitmap, 0, 0, paint);  
            mPhoto.setImageBitmap(destBitmap); 
			break;
		case R.id.blue:
            mBlue = 127 - progress;  
            cMatrix = new ColorMatrix();  
            cMatrix.set(new float[] { mContrast, 0, 0, 0, mBrightness+mRed, 
            		0, mContrast, 0, 0, mBrightness+mGreen,
                    0, 0, mContrast, 0, mBrightness+mBlue, 
                    0, 0, 0, 1, 0 });  

            paint = new Paint();  
            paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));  

            canvas = new Canvas(destBitmap);  
            // 在Canvas上绘制一个已经存在的Bitmap。这样，dstBitmap就和srcBitmap一摸一样了   
            canvas.drawBitmap(srcBitmap, 0, 0, paint);  
            mPhoto.setImageBitmap(destBitmap); 
			break;
		}
	}

	public void onStartTrackingTouch(SeekBar seekBar) {
		// TODO Auto-generated method stub
		
	}

	public void onStopTrackingTouch(SeekBar seekBar) {
		// TODO Auto-generated method stub
		
	}
	
	private void rotateLargeBitmap(int degree, BitmapRegionDecoder regionDecoder, Bitmap destBitmap) {
		final Canvas canvas = new Canvas(destBitmap);
		final int width = regionDecoder.getWidth();
		final int height = regionDecoder.getHeight();
		final int stepWidth = width/3;
		final int stepHeight = height/3;
		final int dxy = (height-width)/2;
		if (SmallphoneScannerActivity.LOG) {
			Log.d(TAG, "rotate degree:"+degree);
			Log.d(TAG, "regionDecoder size:["+width+"]["+height+"]");
			Log.d(TAG, "canvas size:["+canvas.getWidth()+"]["+canvas.getHeight()+"]");
			Log.d(TAG, "step size:["+stepWidth+"]["+stepHeight+"]");
		}
		
		canvas.rotate(degree, canvas.getWidth()/2, canvas.getHeight()/2);
		Paint paint = new Paint();
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				Bitmap bm = regionDecoder.decodeRegion(new Rect(stepWidth*i, stepHeight*j, stepWidth*(i+1), stepHeight*(j+1)), null);
				if (SmallphoneScannerActivity.LOG) {
					Log.d(TAG, "temp bitmap size:["+bm.getWidth()+"]["+bm.getHeight()+"]");
				}
				canvas.drawBitmap(bm, stepWidth*i+dxy, stepHeight*j-dxy, paint);
				bm.recycle();
			}
		}
	}
}
